Move the tracking rect workaround from here...
authorRichard Hult <richard@imendio.com>
Thu, 10 Jan 2008 19:35:53 +0000 (19:35 +0000)
committerRichard Hult <rhult@src.gnome.org>
Thu, 10 Jan 2008 19:35:53 +0000 (19:35 +0000)
2008-01-10  Richard Hult  <richard@imendio.com>

* gdk/quartz/gdkwindow-quartz.c: (show_window_internal),
(gdk_window_hide), (move_resize_window_internal): Move the
tracking rect workaround from here...

* gdk/quartz/GdkQuartzWindow.c:
* gdk/quartz/GdkQuartzWindow.h: ...to here, and ignore window
movements during showing/hiding operations. Fixes bug #508516.

svn path=/trunk/; revision=19342

ChangeLog
gdk/quartz/GdkQuartzWindow.c
gdk/quartz/GdkQuartzWindow.h
gdk/quartz/gdkwindow-quartz.c

index a07066dd6fb77c232481654b6257bb4c5eaa750d..65ab438e91bd48087702d7d7523b2b11ace742b4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2008-01-10  Richard Hult  <richard@imendio.com>
+
+       * gdk/quartz/gdkwindow-quartz.c: (show_window_internal),
+       (gdk_window_hide), (move_resize_window_internal): Move the
+       tracking rect workaround from here...
+
+       * gdk/quartz/GdkQuartzWindow.c:
+       * gdk/quartz/GdkQuartzWindow.h: ...to here, and ignore window
+       movements during showing/hiding operations. Fixes bug #508516.
+
 2008-01-10  Michael Natterer  <mitch@imendio.com>
 
        * gdk/directfb/gdkscreen-directfb.c
index b5c751d4430e4a04d04dc2aa15127a4d5ea2b696..d1ecbfdfa9a27af2cc6a1db0afd95caa327810df 100644 (file)
   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
   GdkEvent *event;
 
+  /* Ignore new position during showing/hiding the window, otherwise we
+   * would get the off-screen position that is used for hidden windows to
+   * get reliable MouseEntered events when showing them again. See comments
+   * in show() and hide().
+   */
+  if (inShowOrHide)
+    return;
+
   private->x = content_rect.origin.x;
   private->y = _gdk_quartz_window_get_inverted_screen_y (content_rect.origin.y + content_rect.size.height);
 
   return YES;
 }
 
+- (void)showAndMakeKey:(BOOL)makeKey
+{
+  GdkWindow *window = [[self contentView] gdkWindow];
+  GdkWindowObject *private = (GdkWindowObject *)window;
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+
+  inShowOrHide = YES;
+
+  if (!GDK_WINDOW_IS_MAPPED (window))
+    {
+      NSRect content_rect;
+      NSRect frame_rect;
+
+      /* We move the window in place if it's not mapped. See comment in
+       * hide().
+       */
+      content_rect =
+        NSMakeRect (private->x,
+                    _gdk_quartz_window_get_inverted_screen_y (private->y) - impl->height,
+                    impl->width, impl->height);
+      frame_rect = [impl->toplevel frameRectForContentRect:content_rect];
+      [impl->toplevel setFrame:frame_rect display:NO];
+    }
+
+  if (makeKey)
+    [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
+  else
+    [impl->toplevel orderFront:nil];
+
+  inShowOrHide = NO;
+}
+
+- (void)hide
+{
+  GdkWindow *window = [[self contentView] gdkWindow];
+  GdkWindowObject *private = (GdkWindowObject *)window;
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+  NSRect content_rect;
+  NSRect frame_rect;
+
+  inShowOrHide = YES;
+
+  /* We move the window away when hiding, to make it possible to move it in
+   * place when showing to get reliable tracking rect events (which are used
+   * to generate crossing events). We have to do this, probably a bug in
+   * quartz.
+   */
+  content_rect = NSMakeRect (-500 - impl->width, -500 - impl->height,
+                             impl->width, impl->height);
+  frame_rect = [impl->toplevel frameRectForContentRect:content_rect];
+  [impl->toplevel setFrame:frame_rect display:NO];
+
+  [impl->toplevel orderOut:nil];
+
+  inShowOrHide = NO;
+}
+
 - (BOOL)trackManualMove
 {
   NSPoint currentLocation;
index 37271790aad44ea9295fbc64b8e1e9c74e38cc17..e6d1b4e155eb4ba80b846034c62eb19b932f7eac 100644 (file)
@@ -23,7 +23,8 @@
 #include <glib.h>
 
 @interface GdkQuartzWindow : NSWindow {
-  BOOL inMove;
+  BOOL    inMove;
+  BOOL    inShowOrHide;
 
   /* Manually triggered move/resize (not by the window manager) */
   BOOL    inManualMove;
@@ -39,6 +40,8 @@
 -(BOOL)trackManualMove;
 -(void)beginManualResize;
 -(BOOL)trackManualResize;
+-(void)showAndMakeKey:(BOOL)makeKey;
+-(void)hide;
 
 @end
 
index f57f51ed9db897ead70318669c4700fe74313743..a5dfa595b45a739cb58fd3d377ab8d4235920aea 100644 (file)
@@ -976,30 +976,15 @@ show_window_internal (GdkWindow *window,
 
   if (impl->toplevel)
     {
+      gboolean make_key;
+
       /* Move the window into place, to guarantee that we get the
        * initial MouseEntered event.
        */
-      if (!GDK_WINDOW_IS_MAPPED (window))
-        {
-          NSRect content_rect;
-          NSRect frame_rect;
-
-          content_rect =
-            NSMakeRect (private->x,
-                        _gdk_quartz_window_get_inverted_screen_y (private->y) - impl->height,
-                        impl->width, impl->height);
-          frame_rect = [impl->toplevel frameRectForContentRect:content_rect];
-          [impl->toplevel setFrame:frame_rect display:NO];
-        }
+      make_key = (private->accept_focus && focus_on_map && raise && 
+                  private->window_type != GDK_WINDOW_TEMP);
 
-      /* We should make the window not raise for !raise, but at least
-       * this will keep it from getting focused in that case.
-       */
-      if (private->accept_focus && focus_on_map && raise &&
-          private->window_type != GDK_WINDOW_TEMP)
-        [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
-      else
-        [impl->toplevel orderFront:nil];
+      [(GdkQuartzWindow*)impl->toplevel showAndMakeKey:make_key];
     }
   else
     {
@@ -1124,16 +1109,7 @@ gdk_window_hide (GdkWindow *window)
       if (impl->transient_for)
         _gdk_quartz_window_detach_from_parent (window);
 
-      /* Big hack in gdk_window_new() and show_window_internal()
-       * continued. Move the window away when hidden so that we can
-       * move it back before showing it.
-       */
-      content_rect = NSMakeRect (-500 - impl->width, -500 - impl->height,
-                                 impl->width, impl->height);
-      frame_rect = [impl->toplevel frameRectForContentRect:content_rect];
-      [impl->toplevel setFrame:frame_rect display:NO];
-
-      [impl->toplevel orderOut:nil];
+      [(GdkQuartzWindow*)impl->toplevel hide];
     }
   else if (impl->view)
     {
@@ -1228,12 +1204,19 @@ move_resize_window_internal (GdkWindow *window,
       NSRect content_rect;
       NSRect frame_rect;
 
-      content_rect =  NSMakeRect (private->x,
-                                  _gdk_quartz_window_get_inverted_screen_y (private->y + impl->height),
-                                  impl->width, impl->height);
-      
-      frame_rect = [impl->toplevel frameRectForContentRect:content_rect];
-      [impl->toplevel setFrame:frame_rect display:YES];
+      /* We don't update the NSWindow while unmapped, since we move windows
+       * off-screen when hiding in order for MouseEntered to be triggered
+       * reliably when showing windows and they appear under the mouse.
+       */
+      if (GDK_WINDOW_IS_MAPPED (window))
+        {
+          content_rect =  NSMakeRect (private->x,
+                                      _gdk_quartz_window_get_inverted_screen_y (private->y + impl->height),
+                                      impl->width, impl->height);
+
+          frame_rect = [impl->toplevel frameRectForContentRect:content_rect];
+          [impl->toplevel setFrame:frame_rect display:YES];
+        }
     }
   else 
     {